package com.hantanger.weblog.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hantanger.weblog.controller.AlbumController;
import com.hantanger.weblog.controller.BaseController;
import com.hantanger.weblog.controller.CronController;
import com.hantanger.weblog.controller.FileController;
import com.hantanger.weblog.controller.HomeController;
import com.hantanger.weblog.controller.InitController;
import com.hantanger.weblog.controller.JsonController;
import com.hantanger.weblog.controller.LoginoutController;
import com.hantanger.weblog.controller.PostEditController;
import com.hantanger.weblog.controller.PostListController;
import com.hantanger.weblog.controller.PostSingleController;
import com.hantanger.weblog.controller.RsdController;
import com.hantanger.weblog.controller.RssController;
import com.hantanger.weblog.controller.SettingController;
import com.hantanger.weblog.controller.SitemapController;
import com.hantanger.weblog.controller.TaskController;
import com.hantanger.weblog.controller.UploadController;
import com.hantanger.weblog.controller.XmlRpcController;
import com.hantanger.weblog.util.ClassFactory;

/**
 * 负责本blog请求的转发
 */
@SuppressWarnings("serial")
public class DispatcherServlet extends HttpServlet {
	
	private static final Logger log = Logger.getLogger(DispatcherServlet.class.getName());
	
	private static Map<String, Class<? extends BaseController>> actionMap = new HashMap<String, Class<? extends BaseController>>();

	// 初始化URL映射
	static {
		actionMap.put("^/home.do$", HomeController.class);
		actionMap.put("^/album.do$", AlbumController.class);
		actionMap.put("^/post_prev.do$", PostSingleController.class);
		actionMap.put("^/post_edit.do$", PostEditController.class);
		actionMap.put("^/post_list.do$", PostListController.class);
		actionMap.put("^/post_json.do$", JsonController.class);
		actionMap.put("^/upload.do$", UploadController.class);
		actionMap.put("^/file.do$", FileController.class);
		actionMap.put("^/setting.do$", SettingController.class);
		actionMap.put("^/cron.do$", CronController.class);
		actionMap.put("^/task.do$", TaskController.class);
		actionMap.put("^/rss.do$", RssController.class);
		actionMap.put("^/sitemap.do$", SitemapController.class);
		actionMap.put("^/xmlrpc.do$", XmlRpcController.class);
		actionMap.put("^/loginout.do$", LoginoutController.class);
		actionMap.put("^/init.do$", InitController.class);
		actionMap.put("^/rsd.do$", RsdController.class);
	}

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		req.setAttribute("isSpider", false);
		String userAgent = req.getHeader("User-Agent");
		if (userAgent != null) {
			if (userAgent.indexOf("google") != -1
					|| userAgent.indexOf("baidu") != -1
					|| userAgent.indexOf("sogou") != -1
					|| userAgent.indexOf("yahoo") != -1
					|| userAgent.indexOf("sogou") != -1
					|| userAgent.indexOf("sina") != -1
					|| userAgent.indexOf("soso") != -1) {
				req.setAttribute("isSpider", true);
			}
			log.info(userAgent);
		}
		
		BaseController action = findActionMap(req.getRequestURI());
		String desTemplateName = "/index.ftl";
		if(action == null){
			desTemplateName = "error";
			req.setAttribute("errorMsg", "error");
		}else{
			String pageName = action.process(req, resp);
			if(pageName == null){
				return;
			}
			
			req.setAttribute("pageName", pageName);
			if("post_more".equals(pageName)){
				desTemplateName = "/postlist.ftl";
			}
			
			if("error".equals(pageName)){
				doError(req, resp);
				return;
			}
		}
		
		RequestDispatcher dispatcher = req.getRequestDispatcher(desTemplateName);
		try {
			dispatcher.forward(req, resp);
		} catch (ServletException e) {
			req.setAttribute("errorMsg", e.getMessage());
			e.printStackTrace();
		}
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		doGet(req, resp);
	}
	
	private void doError(HttpServletRequest req, HttpServletResponse resp) throws IOException{
		resp.setStatus(404);
		RequestDispatcher dispatcher = req.getRequestDispatcher("/error.ftl");
		try {
			dispatcher.forward(req, resp);
		} catch (ServletException e) {
			e.printStackTrace();
		}
	}

	// 查找URI对应的处理类
	private BaseController findActionMap(String uri) {
		for (String uriPattern : actionMap.keySet()) {
			Matcher matcher = Pattern.compile(uriPattern).matcher(uri);
			if (matcher.matches()) {
				return ClassFactory.getInstance(actionMap.get(uriPattern));
			}
		}
		return null;
	}
}
